package uk.co.accolade.clash.app.intellij.toolwindow;

import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.fileEditor.FileEditorManager;

import javax.swing.event.TreeSelectionListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.tree.TreePath;
import java.io.File;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class JumpToFile implements TreeSelectionListener {

    private static final Log LOG = LogFactory.getLog( JumpToFile.class );

    private static final int FILE_NODE_DEPTH = 3;

    private LocalFileSystem localFileSystem;
    private FileEditorManager fileEditorManager;
    private String projectDir;

    public static JumpToFile createInstance( Project project ) {
        return new JumpToFile(
                LocalFileSystem.getInstance(),
                FileEditorManager.getInstance( project ),
                project.getBaseDir().getPath() );        
    }

    protected JumpToFile( LocalFileSystem localFileSystem, FileEditorManager fileEditorManager, String projectDir ) {
        this.localFileSystem = localFileSystem;
        this.fileEditorManager = fileEditorManager;
        this.projectDir = projectDir;
    }

    public void valueChanged( TreeSelectionEvent event ) {
        TreePath selectedPath = event.getPath();
        if( isFileNode( selectedPath ) && nodeHasChanged( event ) ) {
            String filePath = selectedPath.getLastPathComponent().toString();
            VirtualFile fileToOpen = localFileSystem.findFileByIoFile( new File( projectDir + filePath) );
            if( fileToOpen != null )  {
                fileEditorManager.openFile( fileToOpen, true );
            } else {
                LOG.info( "Could not find file to open: " + filePath );
            }
        }
    }

    private boolean nodeHasChanged( TreeSelectionEvent event ) {
        return !event.getPath().equals( event.getOldLeadSelectionPath() );
    }

    private boolean isFileNode( TreePath selectedPath ) {
        return selectedPath.getPath().length == FILE_NODE_DEPTH;
    }
}
